AWS Parameters and Secrets Lambda Extensionを使用してみた
AWS Parameters and Secrets Lambda Extensionとは?
AWS Parameters and Secrets Lambda Extensionを使用すると、Lambda 関数の AWS Secrets ManagerのシークレットとParameter Storeのパラメータを取得してキャッシュできます。
AWS Parameters and Secrets Lambda Extensionを使用するメリット:
- キャッシュされたシークレットまたはキャッシュされたパラメーターの取得は、それぞれ Secrets Manager またはParameter Storeアから取得するよりも高速です。そのため、関数の実行時間を短縮することができます。
- APIのコストを短縮することができます。
AWS Parameters and Secrets Lambda Extensionは、localhost ポート 2773 にリクエストを行います。PARAMETERS_SECRETS_EXTENSION_HTTP_PORT : 2773を環境変数として設定します。
この記事では、AWS Parameters and Secrets Lambda Extensionを使用して、Lambda 関数で AWS Secrets Manager シークレットを取得してキャッシュしてみました。
やってみた
Secrets Managerでシークレットの作成
- Secrets Manager のコンソールで[Store a new secret]を選択しておきます。
- [Other type of secret] をシークレットタイプとして選択します。
- シークレットをキー/値ペアとして入力しておきます。
- シークレットの名前を入力し、他の設定をデフォルト値のままにしてシークレットをStoreしておきます。
Lambda関数の作成
- Python ランタイムで Lambda 関数を作成しておきます。最新の Python バージョンでは「No module named requests」エラーが発生するため、今回は Python 3.7 を使用します。
- Lambda が Secrets Manager シークレットにアクセスできるようにする権限を持つ IAM ポリシーを作成し、このポリシーを Lambda 実行ロールにアタッチしておきます。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "secretsmanager:GetSecretValue" ], "Resource": [ "arn:aws:secretsmanager:<region>:<account-id>:secret:*" ] } ] }
Extensionを使用せずにLambdaの実行時間の確認
- Python コードを以下のコードに置き換えます。これは、Lambda を実行するたびに Secret Manager からシークレットを取得します。
import json import boto3 def lambda_handler(event, context): client = boto3.client('secretsmanager') secret = client.get_secret_value(SecretId='lambda-secret') return secret['SecretString']
- 初めて Lambda 関数を実行するときに Secrets Manager からシークレットを取得するのにかかる時間は約 1640.58 ミリ秒です。
- その後の Lambda の実行では、シークレットを取得する時間は 1640.58 ミリ秒から 265.77 ミリ秒に短縮されました。
Extensionを使用しているLambdaの実行時間の確認
Lambda 関数にレイヤーを追加する
- Lambda コンソールで関数を選択し、Layersを選択して、Add a layerを選択しておきます。
- AWS layers で [AWS Parameters and Secrets Lambda Extension] を選択して、レイヤーを追加しておきます。
Lambda 関数に環境変数を追加する
- Lambda 関数を開き、Configurationで Environment variables を選択し、Edit をクリックしておきます。
- [Add environment variable]をクリックし、キーとして [PARAMETERS_SECRETS_EXTENSION_HTTP_PORT] を入力し、[2773] を値としてを入力し、保存しておきます。
拡張キャッシュからシークレットを取得する Python コード
- 拡張キャッシュからシークレットを取得するために、コードのリクエストヘッダーに [X-AWS-Parameters-Secrets-Token] を追加しておきます。
- トークンを[AWS_SESSION_TOKEN]に設定しておきます。
- 以下はシークレットを取得するコードです。
import json import boto3 import os import requests def lambda_handler(event, context): headers = {"X-Aws-Parameters-Secrets-Token": os.environ.get('AWS_SESSION_TOKEN')} SECRETS_EXTENSION_PORT = os.environ.get('PARAMETERS_SECRETS_EXTENSION_HTTP_PORT') secrets_extension_endpoint = f"http://localhost:{SECRETS_EXTENSION_PORT}/secretsmanager/get?secretId=lambda-secret" req = requests.get(secrets_extension_endpoint, headers=headers) secret = json.loads(req.text)["SecretString"] return secret
- 初めて Lambda 関数を実行するときに Secrets Manager からシークレットを取得するのにかかる時間は約 697.25 ミリ秒です。
- その後の Lambda の実行では、シークレットを取得する時間は 697.25 ミリ秒から 29.81 ミリ秒に短縮されました。シークレットがキャッシュから取得されるため、時間が短縮されました。
まとめ
シークレットを取得する時間は、Secrets Manager から取得する場合に比べて大幅に短縮されました。キャッシュされたシークレットの取得は Secrets Manager からの取得よりも高速です。[AWS Parameters and Secrets Lambda Extension] を使用して、Parameter Store パラメータを取得してキャッシュすることもできます。
Reference : Use AWS Secrets Manager secrets in AWS Lambda functions